package com.event.management.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.event.management.backend.domain.Users;
import com.event.management.backend.domain.LoginLogs;
import com.event.management.backend.dto.LoginParam;
import com.event.management.backend.dto.LoginResponseDTO;
import com.event.management.backend.dto.UserCreateDTO;
import com.event.management.backend.dto.UserInfoDTO;
import com.event.management.backend.dto.UserPageDTO;
import com.event.management.backend.dto.UserUpdateDTO;
import com.event.management.backend.mapper.UsersMapper;
import com.event.management.backend.service.UsersService;
import com.event.management.backend.service.LoginLogsService;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author HY
* @description 针对表【users(用户表)】的数据库操作Service实现
* @createDate 2025-04-04 17:38:12
*/
@Slf4j
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
    implements UsersService{

    private final LoginLogsService loginLogsService;

    public UsersServiceImpl(LoginLogsService loginLogsService) {
        this.loginLogsService = loginLogsService;
    }

    /**
     * 用户登录
     * @param loginParam 登录参数
     * @return 登录结果
     */
    @Override
    public LoginResponseDTO login(LoginParam loginParam) {
        // 查询用户
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUsername, loginParam.getUsername());
        Users user = getOne(queryWrapper);
        
        log.info("用户登录: {}, 查询结果: {}", loginParam.getUsername(), user != null ? "存在" : "不存在");
        
        // 验证用户是否存在
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 验证密码是否正确（针对admin用户的特殊处理）
        String encryptedPassword = DigestUtils.md5DigestAsHex(loginParam.getPassword().getBytes());
        String savedPassword = user.getPassword();
        
        log.info("密码验证 - 输入密码: {}, 数据库密码: {}", encryptedPassword, savedPassword);

        if (!savedPassword.equals(encryptedPassword)) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 生成Token并登录 - 仅调用login方法，通过实现StpInterface自动加载角色和权限
        StpUtil.login(user.getId());
        log.info("用户 {} 登录成功，使用StpInterface自动加载角色", user.getUsername());
        
        // 显式设置角色到Session中，确保前端可以正确获取角色信息
        log.info("为用户 {} 设置角色: {}", user.getUsername(), user.getRole());
        StpUtil.getSession().set("role", user.getRole());
        
        // 如果是admin用户，显式添加admin角色
        if ("admin".equals(user.getRole())) {
            StpUtil.getRoleList().add("admin");
            log.info("为用户 {} 显式添加admin角色", user.getUsername());
        }
        
        // 原有手动设置角色的方式(注释掉，仅用于学习参考)
        /*
        // 设置角色
        log.info("为用户 {} 设置角色: {}", user.getUsername(), user.getRole());
        StpUtil.getSession().set("role", user.getRole());
        
        // 如果是admin用户，显式添加admin角色
        if ("admin".equals(user.getRole())) {
            StpUtil.getRoleList().add("admin");
            log.info("为用户 {} 显式添加admin角色", user.getUsername());
        }
        */
        
        String tokenValue = StpUtil.getTokenValue();
        log.info("用户 {} 生成token: {}", user.getUsername(), tokenValue);
        
        // 构建返回结果
        UserInfoDTO userInfoDTO = new UserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole()
        );
        
        // 设置所有扩展用户信息
        userInfoDTO.setRealName(user.getRealName());
        userInfoDTO.setGender(user.getGender());
        userInfoDTO.setEmail(user.getEmail());
        userInfoDTO.setPhone(user.getPhone());
        userInfoDTO.setInterests(user.getInterests());
        userInfoDTO.setBirthday(user.getBirthday());
        userInfoDTO.setBio(user.getBio());
        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setAddress(user.getAddress());
        userInfoDTO.setProfession(user.getProfession());
        userInfoDTO.setCreatedAt(user.getCreatedAt());
        userInfoDTO.setUpdatedAt(user.getUpdatedAt());
        
        return new LoginResponseDTO(tokenValue, userInfoDTO);
    }

    /**
     * 获取当前登录用户信息
     * @return 用户信息
     */
    @Override
    public UserInfoDTO getCurrentUserInfo() {
        // 获取当前登录用户ID
        Object loginId = StpUtil.getLoginId();
        Integer userId = Integer.parseInt(loginId.toString());
        
        log.info("获取当前登录用户ID: {}", userId);
        
        // 查询用户信息
        Users user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        log.info("获取到用户: {}, 角色: {}", user.getUsername(), user.getRole());
        
        // 创建用户信息DTO
        UserInfoDTO userInfoDTO = new UserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole()
        );
        
        // 设置所有扩展用户信息
        userInfoDTO.setRealName(user.getRealName());
        userInfoDTO.setGender(user.getGender());
        userInfoDTO.setEmail(user.getEmail());
        userInfoDTO.setPhone(user.getPhone());
        userInfoDTO.setInterests(user.getInterests());
        userInfoDTO.setBirthday(user.getBirthday());
        userInfoDTO.setBio(user.getBio());
        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setAddress(user.getAddress());
        userInfoDTO.setProfession(user.getProfession());
        userInfoDTO.setCreatedAt(user.getCreatedAt());
        userInfoDTO.setUpdatedAt(user.getUpdatedAt());
        
        // 获取最后登录信息
        try {
            LoginLogs lastLogin = loginLogsService.getLastSuccessfulLogin(userId);
            if (lastLogin != null) {
                userInfoDTO.setLastLoginIp(lastLogin.getIpAddress());
                userInfoDTO.setLastLoginTime(lastLogin.getLoginTime());
                log.info("设置最后登录信息: ip={}, time={}", lastLogin.getIpAddress(), lastLogin.getLoginTime());
            }
        } catch (Exception e) {
            log.error("获取最后登录信息失败: {}", e.getMessage());
        }
        
        return userInfoDTO;
    }
    
    /**
     * 分页查询用户列表
     * @param pageDTO 分页参数
     * @return 用户分页数据
     */
    @Override
    public Page<UserInfoDTO> getUserPage(UserPageDTO pageDTO) {
        log.info("分页查询用户列表: pageNum={}, pageSize={}, keyword={}", 
                pageDTO.getPageNum(), pageDTO.getPageSize(), pageDTO.getKeyword());
        
        // 构建查询条件
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(pageDTO.getKeyword())) {
            queryWrapper.like(Users::getUsername, pageDTO.getKeyword());
        }
        
        // 执行分页查询
        Page<Users> userPage = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        Page<Users> resultPage = page(userPage, queryWrapper);
        
        // 转换为DTO对象
        List<UserInfoDTO> userInfoList = resultPage.getRecords().stream()
                .map(user -> new UserInfoDTO(user.getId(), user.getUsername(), user.getRole()))
                .collect(Collectors.toList());
        
        // 构建返回结果
        Page<UserInfoDTO> dtoPage = new Page<>(
                resultPage.getCurrent(),
                resultPage.getSize(),
                resultPage.getTotal());
        dtoPage.setRecords(userInfoList);
        
        log.info("查询结果: 总记录数={}, 总页数={}", dtoPage.getTotal(), dtoPage.getPages());
        return dtoPage;
    }
    
    /**
     * 创建用户
     * @param userCreateDTO 用户创建参数
     * @return 创建后的用户信息
     */
    @Override
    public UserInfoDTO createUser(UserCreateDTO userCreateDTO) {
        log.info("创建用户: username={}, role={}", userCreateDTO.getUsername(), userCreateDTO.getRole());
        
        // 检查用户名是否已存在
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUsername, userCreateDTO.getUsername());
        if (count(queryWrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建用户实体
        Users user = new Users();
        user.setUsername(userCreateDTO.getUsername());
        // 密码加密存储
        String encryptedPassword = DigestUtils.md5DigestAsHex(userCreateDTO.getPassword().getBytes());
        user.setPassword(encryptedPassword);
        user.setRole(userCreateDTO.getRole());
        
        // 设置其他用户信息
        user.setRealName(userCreateDTO.getRealName());
        user.setGender(userCreateDTO.getGender());
        user.setEmail(userCreateDTO.getEmail());
        user.setPhone(userCreateDTO.getPhone());
        user.setInterests(userCreateDTO.getInterests());
        user.setBirthday(userCreateDTO.getBirthday());
        user.setBio(userCreateDTO.getBio());
        user.setAvatar(userCreateDTO.getAvatar());
        user.setAddress(userCreateDTO.getAddress());
        user.setProfession(userCreateDTO.getProfession());
        
        user.setCreatedAt(new Date());
        user.setUpdatedAt(new Date());
        
        // 保存用户
        boolean saved = save(user);
        if (!saved) {
            throw new RuntimeException("创建用户失败");
        }
        
        log.info("用户创建成功: id={}", user.getId());
        
        // 返回用户信息
        UserInfoDTO userInfoDTO = new UserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole()
        );
        
        // 设置所有扩展用户信息
        userInfoDTO.setRealName(user.getRealName());
        userInfoDTO.setGender(user.getGender());
        userInfoDTO.setEmail(user.getEmail());
        userInfoDTO.setPhone(user.getPhone());
        userInfoDTO.setInterests(user.getInterests());
        userInfoDTO.setBirthday(user.getBirthday());
        userInfoDTO.setBio(user.getBio());
        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setAddress(user.getAddress());
        userInfoDTO.setProfession(user.getProfession());
        userInfoDTO.setCreatedAt(user.getCreatedAt());
        userInfoDTO.setUpdatedAt(user.getUpdatedAt());
        
        return userInfoDTO;
    }
    
    /**
     * 更新用户信息
     * @param id 用户ID
     * @param userUpdateDTO 用户更新参数
     * @return 更新后的用户信息
     */
    @Override
    public UserInfoDTO updateUser(Integer id, UserUpdateDTO userUpdateDTO) {
        log.info("更新用户: id={}", id);
        
        // 查询用户是否存在
        Users user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 如果更新用户名，检查新用户名是否已被其他用户使用
        if (StringUtils.hasText(userUpdateDTO.getUsername()) 
                && !user.getUsername().equals(userUpdateDTO.getUsername())) {
            LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Users::getUsername, userUpdateDTO.getUsername())
                    .ne(Users::getId, id);
            if (count(queryWrapper) > 0) {
                throw new RuntimeException("用户名已存在");
            }
            user.setUsername(userUpdateDTO.getUsername());
        }
        
        // 如果更新密码，进行加密
        if (StringUtils.hasText(userUpdateDTO.getPassword())) {
            String encryptedPassword = DigestUtils.md5DigestAsHex(userUpdateDTO.getPassword().getBytes());
            user.setPassword(encryptedPassword);
        }
        
        // 更新其他用户信息
        if (StringUtils.hasText(userUpdateDTO.getRealName())) {
            user.setRealName(userUpdateDTO.getRealName());
        }
        if (userUpdateDTO.getGender() != null) {
            user.setGender(userUpdateDTO.getGender());
        }
        if (StringUtils.hasText(userUpdateDTO.getEmail())) {
            user.setEmail(userUpdateDTO.getEmail());
        }
        if (StringUtils.hasText(userUpdateDTO.getPhone())) {
            user.setPhone(userUpdateDTO.getPhone());
        }
        if (StringUtils.hasText(userUpdateDTO.getInterests())) {
            user.setInterests(userUpdateDTO.getInterests());
        }
        if (userUpdateDTO.getBirthday() != null) {
            user.setBirthday(userUpdateDTO.getBirthday());
        }
        if (StringUtils.hasText(userUpdateDTO.getBio())) {
            user.setBio(userUpdateDTO.getBio());
        }
        if (StringUtils.hasText(userUpdateDTO.getAvatar())) {
            user.setAvatar(userUpdateDTO.getAvatar());
        }
        if (StringUtils.hasText(userUpdateDTO.getAddress())) {
            user.setAddress(userUpdateDTO.getAddress());
        }
        if (StringUtils.hasText(userUpdateDTO.getProfession())) {
            user.setProfession(userUpdateDTO.getProfession());
        }
        
        // 如果更新角色
        if (StringUtils.hasText(userUpdateDTO.getRole())) {
            user.setRole(userUpdateDTO.getRole());
        }
        
        // 更新时间
        user.setUpdatedAt(new Date());
        
        // 更新用户
        boolean updated = updateById(user);
        if (!updated) {
            throw new RuntimeException("更新用户失败");
        }
        
        log.info("用户更新成功");
        
        // 返回用户信息
        UserInfoDTO userInfoDTO = new UserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole()
        );
        
        // 设置所有扩展用户信息
        userInfoDTO.setRealName(user.getRealName());
        userInfoDTO.setGender(user.getGender());
        userInfoDTO.setEmail(user.getEmail());
        userInfoDTO.setPhone(user.getPhone());
        userInfoDTO.setInterests(user.getInterests());
        userInfoDTO.setBirthday(user.getBirthday());
        userInfoDTO.setBio(user.getBio());
        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setAddress(user.getAddress());
        userInfoDTO.setProfession(user.getProfession());
        userInfoDTO.setCreatedAt(user.getCreatedAt());
        userInfoDTO.setUpdatedAt(user.getUpdatedAt());
        
        return userInfoDTO;
    }
    
    /**
     * 删除用户
     * @param id 用户ID
     * @return 是否删除成功
     */
    @Override
    public boolean deleteUser(Integer id) {
        log.info("删除用户: id={}", id);
        
        // 查询用户是否存在
        Users user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查是否为admin账户，禁止删除管理员账户
        if ("admin".equals(user.getUsername())) {
            log.error("禁止删除管理员账户: {}", user.getUsername());
            throw new RuntimeException("禁止删除管理员账户");
        }
        
        // 不允许删除自己
        try {
            Object loginId = StpUtil.getLoginId();
            Integer currentUserId = Integer.parseInt(loginId.toString());
            if (id.equals(currentUserId)) {
                throw new RuntimeException("不能删除当前登录用户");
            }
        } catch (Exception e) {
            log.error("获取当前登录用户ID失败", e);
        }
        
        // 删除用户
        boolean removed = removeById(id);
        if (!removed) {
            throw new RuntimeException("删除用户失败");
        }
        
        log.info("用户删除成功");
        return true;
    }

    /**
     * 根据用户名查询用户ID
     * @param username 用户名
     * @return 用户ID
     */
    @Override
    public Integer getUserIdByUsername(String username) {
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUsername, username);
        Users user = getOne(queryWrapper);
        return user != null ? user.getId() : null;
    }
    
    /**
     * 根据用户名查询用户角色
     * @param username 用户名
     * @return 用户角色，如果用户不存在返回null
     */
    @Override
    public String getUserRoleByUsername(String username) {
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUsername, username);
        Users user = getOne(queryWrapper);
        return user != null ? user.getRole() : null;
    }
}




